﻿using System;
using System.Drawing;
using System.Windows.Forms;
using System.Collections.Generic;

//zedGraph assemblies
using ZedGraph;

namespace iPower
{
    /* http://stackoverflow.com/questions/3478482/how-to-add-real-time-data-in-a-dual-y-axis-zedgraph-graph-using-c */
    /* http://goorman.free.fr/ZedGraph/zedgraph.org/wiki/index3061.html?title=Display_Dynamic_or_Real-Time_Data */
    /* http://zedgraph.dariowiz.com/indexd0ec.html?title=Smooth_Chart_Demo */

    class DynamicGraph
    {
        // Instance Variables
        /* Graph Control Properties */
        private int posX;
        private int posY;
        private int sizeWidth;
        private int sizeHeight;
        private string GraphName;
        private int timeTick = 0;

        // Create ZedGraph Control
        private ZedGraphControl zedGraph = new ZedGraphControl();

        /* Class Constructor */
        public DynamicGraph(string GraphName)
        {
            this.posX = 6;
            this.posY = 16;
            this.sizeWidth = 1050;
            this.sizeHeight = 270;
            this.GraphName = GraphName;

            setGraphDefaults();
        } //DynamicGraph

        /* Class Constructor - Overloaded */
        public DynamicGraph(int posX, int posY, int sizeWidth, int sizeHeight, string GraphName)
        {
            this.posX = posX;
            this.posY = posY;
            this.sizeWidth = sizeWidth;
            this.sizeHeight = sizeHeight;
            this.GraphName = GraphName;

            setGraphDefaults();
        } //DynamicGraph

        /* Assign Graph to Control */
        public void assignGraph(Control control)
        {
            control.Controls.Clear();

            control.Controls.Add(zedGraph);
        } //assignGraph

        /* Set Default Graph Properties */
        private void setGraphDefaults()
        {
            this.zedGraph.Location = new Point(posX, posY);
            this.zedGraph.Size = new Size(sizeWidth, sizeHeight);
            this.zedGraph.Name = GraphName;            

            this.zedGraph.ScrollGrace = 0D;
            this.zedGraph.ScrollMaxX = 0D;
            this.zedGraph.ScrollMaxY = 0D;
            this.zedGraph.ScrollMaxY2 = 0D;
            this.zedGraph.ScrollMinX = 0D;
            this.zedGraph.ScrollMinY = 0D;
            this.zedGraph.ScrollMinY2 = 0D;
 
        } //setGraphDefaults

        public void updateGraph()
        {
            this.zedGraph.AxisChange();
            this.zedGraph.Invalidate();
        } //updateGraph

        private void removeToolStripItems()
        {
            foreach (ToolStripMenuItem item in this.zedGraph.ContextMenuStrip.Items)
            {
                if ((string)item.Tag == "set_default")
                {
                    // remove the menu item
                    this.zedGraph.ContextMenuStrip.Items.Remove(item);
                    // or, just disable the item with this
                    //item.Enabled = false; 

                    break;
                } //if
            } //foreach

        }//removeMenuContextItems

        // ---------------------------------------------------------------------------------------------------------- //

        /* Set Graph Pane Properties */
        public void setGraphPane(string Title, string XAxizTitle, string YAxizTitle)
        {
            // Reference to Graph Pane
            GraphPane graphPane = zedGraph.GraphPane;

            graphPane.Title.Text = Title;
            graphPane.Chart.Fill.Brush = new SolidBrush(Color.Black);

            graphPane.XAxis.Title.Text = XAxizTitle;
            graphPane.XAxis.MinorGrid.IsVisible = false;
            graphPane.XAxis.MinorGrid.Color = Color.Green;
            graphPane.XAxis.MajorGrid.IsVisible = true;
            graphPane.XAxis.MajorGrid.Color = Color.Green;

            graphPane.YAxis.Title.Text = YAxizTitle;
            graphPane.YAxis.MinorGrid.IsVisible = false;
            graphPane.YAxis.MinorGrid.Color = Color.Green;
            graphPane.YAxis.MajorGrid.IsVisible = true;
            graphPane.YAxis.MajorGrid.Color = Color.Green;

            updateGraph();
        } //setGraphPane

        // ---------------------------------------------------------------------------------------------------------- //
        /* Pane Realtime Curve Creation - overloaded */
        public void createRealtimeCurves(string PhaseText, int DataPoints)
        {
            // Reference to Graph Pane
            GraphPane graphPane = zedGraph.GraphPane;

            // Ringbuffer for Realtime Graph
            RollingPointPairList PhaseAlist = new RollingPointPairList(DataPoints);

            // Create Line Curve for Graph for each Phase
            LineItem PhaseAcurve = graphPane.AddCurve(PhaseText, PhaseAlist, Color.YellowGreen, SymbolType.None);

            // Just manually control the X axis range so it scrolls continuously
            // instead of discrete step-sized jumps            
            graphPane.XAxis.Scale.Min = 0;
            graphPane.XAxis.Scale.Max = 60;
            graphPane.XAxis.Scale.MinorStep = 1;
            graphPane.XAxis.Scale.MajorStep = 5;

            // Scale the axes
            zedGraph.AxisChange();

        } //createRealtimeCurves


        public void createRealtimeCurves(string PhaseAText, string PhaseBText, string PhaseCText, int DataPoints)
        {
            // Reference to Graph Pane
            GraphPane graphPane = zedGraph.GraphPane;

            // Ringbuffer for Realtime Graph
            RollingPointPairList PhaseAlist = new RollingPointPairList(DataPoints);
            RollingPointPairList PhaseBlist = new RollingPointPairList(DataPoints);
            RollingPointPairList PhaseClist = new RollingPointPairList(DataPoints);

            // Create Line Curve for Graph for each Phase
            LineItem PhaseAcurve = graphPane.AddCurve(PhaseAText, PhaseAlist, Color.Red, SymbolType.None);
            LineItem PhaseBcurve = graphPane.AddCurve(PhaseBText, PhaseBlist, Color.Yellow, SymbolType.None);
            LineItem PhaseCcurve = graphPane.AddCurve(PhaseCText, PhaseClist, Color.Blue, SymbolType.None);

            // Just manually control the X axis range so it scrolls continuously
            // instead of discrete step-sized jumps
            graphPane.XAxis.Scale.Min = 0;
            graphPane.XAxis.Scale.Max = 60;
            graphPane.XAxis.Scale.MinorStep = 1;
            graphPane.XAxis.Scale.MajorStep = 5;

            // Scale the axes
            zedGraph.AxisChange();

        } //createRealtimeCurves

        public void createRealtimeCurves(string PhaseAText, string PhaseBText, string PhaseCText, string PhaseNText, int DataPoints)
        {
            // Reference to Graph Pane
            GraphPane graphPane = zedGraph.GraphPane;

            // Ringbuffer for Realtime Graph
            RollingPointPairList PhaseAlist = new RollingPointPairList(DataPoints);
            RollingPointPairList PhaseBlist = new RollingPointPairList(DataPoints);
            RollingPointPairList PhaseClist = new RollingPointPairList(DataPoints);
            RollingPointPairList PhaseNlist = new RollingPointPairList(DataPoints);

            // Create Line Curve for Graph for each Phase
            LineItem PhaseAcurve = graphPane.AddCurve(PhaseAText, PhaseAlist, Color.Red, SymbolType.None);
            LineItem PhaseBcurve = graphPane.AddCurve(PhaseBText, PhaseBlist, Color.Yellow, SymbolType.None);
            LineItem PhaseCcurve = graphPane.AddCurve(PhaseCText, PhaseClist, Color.Blue, SymbolType.None);
            LineItem PhaseNcurve = graphPane.AddCurve(PhaseNText, PhaseNlist, Color.YellowGreen, SymbolType.None);

            // Just manually control the X axis range so it scrolls continuously
            // instead of discrete step-sized jumps
            graphPane.XAxis.Scale.Min = 0;
            graphPane.XAxis.Scale.Max = 60;
            graphPane.XAxis.Scale.MinorStep = 1;
            graphPane.XAxis.Scale.MajorStep = 5;

            // Scale the axes
            zedGraph.AxisChange();

        } //createRealtimeCurves

        /* Update Data in Realtime Graph - normally in timer control */
        public void updateRealtimeCurves(double PhaseVal)
        {
            // Reference to Graph Pane
            GraphPane graphPane = zedGraph.GraphPane;

            // Time is measured in seconds
            int time = this.getTime();

            // Make sure that the curvelist has at least one curve
            if (graphPane.CurveList.Count <= 0)
            {
                return;
            }//if

            // Get the first CurveItem in the graph
            LineItem curvePhase = (LineItem)graphPane.CurveList[0];

            // Get the PointPairList
            IPointListEdit listPhase = (IPointListEdit)curvePhase.Points;
            
            // Add Data to PointList
            listPhase.Add(time, PhaseVal);

            // Keep the X scale at a rolling 30 second interval, with one
            // major step between the max X value and the end of the axis
            Scale xScale = graphPane.XAxis.Scale;

            if (time > xScale.Max - xScale.MajorStep)
            {
                xScale.Max = time + xScale.MajorStep;
                xScale.Min = xScale.Max - 60.0;
            }

            // Make sure Point List and Time match
            if (this.timeTick > listPhase.Count)
            {
                // Clear Time Tick coounter
                this.clearTime();

                // Clear Curve List
                graphPane.CurveList[0].Clear();

                graphPane.XAxis.Scale.Min = 0;
                graphPane.XAxis.Scale.Max = 60;
            }

            // Make sure the Y axis is rescaled to accommodate actual data & Force a redraw
            this.updateGraph();

            // Increment the time 
            this.setTime(1);

        } //updateRealtimeCurves

        public void updateRealtimeCurves(double PhaseAVal, double PhaseBVal, double PhaseCVal)
        {
            // Reference to Graph Pane
            GraphPane graphPane = zedGraph.GraphPane;

            // Time is measured in seconds
            int time = this.getTime();

            // Make sure that the curvelist has at least one curve
            if (graphPane.CurveList.Count <= 0)
            {
                return;
            }//if

            // Get the first CurveItem in the graph
            LineItem curvePhaseA = (LineItem)graphPane.CurveList[0];
            LineItem curvePhaseB = (LineItem)graphPane.CurveList[1];
            LineItem curvePhaseC = (LineItem)graphPane.CurveList[2];           

            // Get the PointPairList
            IPointListEdit listPhaseA = (IPointListEdit)curvePhaseA.Points;
            IPointListEdit listPhaseB = (IPointListEdit)curvePhaseB.Points;
            IPointListEdit listPhaseC = (IPointListEdit)curvePhaseC.Points;            

            // Add Data to PointList
            listPhaseA.Add(time, PhaseAVal);
            listPhaseB.Add(time, PhaseBVal);
            listPhaseC.Add(time, PhaseCVal);

            // Keep the X scale at a rolling 30 second interval, with one
            // major step between the max X value and the end of the axis
            Scale xScale = graphPane.XAxis.Scale;

            if (time > xScale.Max - xScale.MajorStep)
            {
                xScale.Max = time + xScale.MajorStep;
                xScale.Min = xScale.Max - 60.0;
            }

            // Make sure Point List and Time match
            if (this.timeTick > listPhaseA.Count)
            {
                // Clear Time Tick coounter
                this.clearTime();

                // Clear Curve List
                graphPane.CurveList[0].Clear();
                graphPane.CurveList[1].Clear();
                graphPane.CurveList[2].Clear();                

                graphPane.XAxis.Scale.Min = 0;
                graphPane.XAxis.Scale.Max = 60;
            }

            // Make sure the Y axis is rescaled to accommodate actual data & Force a redraw
            this.updateGraph();

            // Increment the time 
            this.setTime(1);

        } //updateRealtimeCurves
        
        
        public void updateRealtimeCurves(double PhaseAVal, double PhaseBVal, double PhaseCVal, double PhaseNVal)
        {
            // Reference to Graph Pane
            GraphPane graphPane = zedGraph.GraphPane;

            // Time is measured in seconds
            int time = this.getTime();

            // Make sure that the curvelist has at least one curve
            if (graphPane.CurveList.Count <= 0)
            {
                return;
            }//if
            
            // Get the first CurveItem in the graph
            LineItem curvePhaseA = (LineItem)graphPane.CurveList[0];
            LineItem curvePhaseB = (LineItem)graphPane.CurveList[1];
            LineItem curvePhaseC = (LineItem)graphPane.CurveList[2];
            LineItem curvePhaseN = (LineItem)graphPane.CurveList[3];

            // Get the PointPairList
            IPointListEdit listPhaseA = (IPointListEdit)curvePhaseA.Points;
            IPointListEdit listPhaseB = (IPointListEdit)curvePhaseB.Points;
            IPointListEdit listPhaseC = (IPointListEdit)curvePhaseC.Points;
            IPointListEdit listPhaseN = (IPointListEdit)curvePhaseN.Points;

            // Add Data to PointList
            listPhaseA.Add(time, PhaseAVal);
            listPhaseB.Add(time, PhaseBVal);
            listPhaseC.Add(time, PhaseCVal);
            listPhaseN.Add(time, PhaseNVal);

            // Keep the X scale at a rolling 30 second interval, with one
            // major step between the max X value and the end of the axis
            Scale xScale = graphPane.XAxis.Scale;

            if (time > xScale.Max - xScale.MajorStep)
            {
                xScale.Max = time + xScale.MajorStep;
                xScale.Min = xScale.Max - 60.0;
            }

            // Make sure Point List and Time match
            if (this.timeTick > listPhaseA.Count)
            {
                // Clear Time Tick coounter
                this.clearTime();

                // Clear Curve List
                graphPane.CurveList[0].Clear();
                graphPane.CurveList[1].Clear();
                graphPane.CurveList[2].Clear();
                graphPane.CurveList[3].Clear();

                graphPane.XAxis.Scale.Min = 0;
                graphPane.XAxis.Scale.Max = 60;
            }

            // Make sure the Y axis is rescaled to accommodate actual data & Force a redraw
            this.updateGraph();

            // Increment the time 
            this.setTime(1);

        }//updateRealtimeCurves

        public void clearCurves()
        {
            // Reference to Graph Pane
            GraphPane graphPane = zedGraph.GraphPane;

            // Iterate over all curveItems in Pane
            foreach (LineItem curveItem in graphPane.CurveList)
            {
                // Clear curveItems
                curveItem.Clear();
            }

            // Reset all Zooming if set by the user
            this.zedGraph.ZoomOutAll(graphPane);

            // Update the graph pane
            this.updateGraph();

        }//clearCurves

        public void setTime(int timeTick)
        {
            this.timeTick += timeTick;
        }//setTime

        public int getTime()
        {
            return this.timeTick;
        }//getTime

        public void clearTime()
        {
            this.timeTick = 0;
        } //clearTime

        // ---------------------------------------------------------------------------------------------------------- //
        /* Historic Graph */

        /* Pane Realtime Curve Creation - overloaded */
        public void createHistoricCurves(string PhaseText)
        {
            // Reference to Graph Pane
            GraphPane graphPane = zedGraph.GraphPane;

            // PointsList for Historic Graph
            PointPairList PhaseAlist = new PointPairList();            

            // Create Line Curve for Graph for each Phase
            LineItem PhaseAcurve = graphPane.AddCurve(PhaseText, PhaseAlist, Color.YellowGreen, SymbolType.None);

            // Set XAxiz to Date Type
            graphPane.XAxis.Type = AxisType.Date;

            // X axis step size is 1 hour
            graphPane.XAxis.Scale.MinorStep = 15;
            graphPane.XAxis.Scale.MinorUnit = DateUnit.Minute;

            // X axis step size is 1 hour
            graphPane.XAxis.Scale.MajorStep = 1;
            graphPane.XAxis.Scale.MajorUnit = DateUnit.Hour;

            // tilt the x axis labels to an angle of 90 degrees
            graphPane.XAxis.Scale.FontSpec.Angle = 90;
            //graphPane.XAxis.Scale.Format = "d HH:mm";
            graphPane.XAxis.Scale.Format = "MM/dd-HH:mm";
            graphPane.XAxis.Scale.FontSpec.Size = 10;
            
            graphPane.YAxis.Scale.FontSpec.Size = 10;

            // Scale the axes
            zedGraph.AxisChange();

        } //createRealtimeCurves

        /* Pane Realtime Curve Creation - overloaded */
        public void createHistoricCurves(string PhaseAText, string PhaseBText, string PhaseCText)
        {
            // Reference to Graph Pane
            GraphPane graphPane = zedGraph.GraphPane;

            // PointsList for Historic Graph
            PointPairList PhaseAlist = new PointPairList();
            PointPairList PhaseBlist = new PointPairList();
            PointPairList PhaseClist = new PointPairList();

            // Create Line Curve for Graph for each Phase
            LineItem PhaseAcurve = graphPane.AddCurve(PhaseAText, PhaseAlist, Color.Red, SymbolType.None);
            LineItem PhaseBcurve = graphPane.AddCurve(PhaseBText, PhaseBlist, Color.Yellow, SymbolType.None);
            LineItem PhaseCcurve = graphPane.AddCurve(PhaseCText, PhaseClist, Color.Blue, SymbolType.None);

            // Set XAxiz to Date Type
            graphPane.XAxis.Type = AxisType.Date;

            // X axis step size is 1 hour
            graphPane.XAxis.Scale.MinorStep = 15;
            graphPane.XAxis.Scale.MinorUnit = DateUnit.Minute;

            // X axis step size is 1 hour
            graphPane.XAxis.Scale.MajorStep = 1;
            graphPane.XAxis.Scale.MajorUnit = DateUnit.Hour;

            // tilt the x axis labels to an angle of 90 degrees
            graphPane.XAxis.Scale.FontSpec.Angle = 90;
            //graphPane.XAxis.Scale.Format = "d HH:mm";
            graphPane.XAxis.Scale.Format = "MM/dd-HH:mm";
            graphPane.XAxis.Scale.FontSpec.Size = 10;

            graphPane.YAxis.Scale.FontSpec.Size = 10;

            // Scale the axes
            zedGraph.AxisChange();

        } //createRealtimeCurves

        /* Pane Realtime Curve Creation - overloaded */
        public void createHistoricCurves(string PhaseAText, string PhaseBText, string PhaseCText, string PhaseNText)
        {
            // Reference to Graph Pane
            GraphPane graphPane = zedGraph.GraphPane;

            // PointsList for Historic Graph
            PointPairList PhaseAlist = new PointPairList();
            PointPairList PhaseBlist = new PointPairList();
            PointPairList PhaseClist = new PointPairList();
            PointPairList PhaseNlist = new PointPairList();

            // Create Line Curve for Graph for each Phase
            LineItem PhaseAcurve = graphPane.AddCurve(PhaseAText, PhaseAlist, Color.Red, SymbolType.None);
            LineItem PhaseBcurve = graphPane.AddCurve(PhaseBText, PhaseBlist, Color.Yellow, SymbolType.None);
            LineItem PhaseCcurve = graphPane.AddCurve(PhaseCText, PhaseClist, Color.Blue, SymbolType.None);
            LineItem PhaseNcurve = graphPane.AddCurve(PhaseNText, PhaseNlist, Color.YellowGreen, SymbolType.None);

            // Set XAxiz to Date Type
            graphPane.XAxis.Type = AxisType.Date;

            // X axis step size is 1 hour
            graphPane.XAxis.Scale.MinorStepAuto = false;
            graphPane.XAxis.Scale.MinorStep = 15;
            graphPane.XAxis.Scale.MinorUnit = DateUnit.Hour;

            // X axis step size is 1 hour
            graphPane.XAxis.Scale.MajorStepAuto = false;
            graphPane.XAxis.Scale.MajorStep = 1;
            graphPane.XAxis.Scale.MajorUnit = DateUnit.Day;

            // tilt the x axis labels to an angle of 90 degrees
            graphPane.XAxis.Scale.FontSpec.Angle = 90;
            //graphPane.XAxis.Scale.Format = "d HH:mm";
            graphPane.XAxis.Scale.Format = "MM/dd-HH:mm";
            graphPane.XAxis.Scale.FontSpec.Size = 10;

            graphPane.YAxis.Scale.FontSpec.Size = 10;

            // Scale the axes
            zedGraph.AxisChange();

        } //createRealtimeCurves



        /* Update Data in Realtime Graph - normally in timer control */
        public void updateHistoricCurves(DateTime DateTime, double PhaseVal)
        {
            // Reference to Graph Pane
            GraphPane graphPane = zedGraph.GraphPane;

            // Make sure that the curvelist has at least one curve
            if (graphPane.CurveList.Count <= 0)
            {
                return;
            }//if

            // Get the first CurveItem in the graph
            LineItem curvePhase = (LineItem)graphPane.CurveList[0];

            // Get the PointPairList
            PointPairList listPhase = (PointPairList)curvePhase.Points;

            // Add Data to PointList
            listPhase.Add((XDate)DateTime, PhaseVal);

            // Make sure the Y axis is rescaled to accommodate actual data & Force a redraw
            this.updateGraph();

        } //updateHistoricCurves


        /* Update Data in Realtime Graph - normally in timer control */
        public void updateHistoricCurves(DateTime DateTime, double PhaseAVal, double PhaseBVal, double PhaseCVal)
        {
            // Reference to Graph Pane
            GraphPane graphPane = zedGraph.GraphPane;

            // Make sure that the curvelist has at least one curve
            if (graphPane.CurveList.Count <= 0)
            {
                return;
            }//if

            // Get the first CurveItem in the graph
            LineItem curveAPhase = (LineItem)graphPane.CurveList[0];
            LineItem curveBPhase = (LineItem)graphPane.CurveList[1];
            LineItem curveCPhase = (LineItem)graphPane.CurveList[2];

            // Get the PointPairList
            PointPairList listPhaseA = (PointPairList)curveAPhase.Points;
            PointPairList listPhaseB = (PointPairList)curveBPhase.Points;
            PointPairList listPhaseC = (PointPairList)curveCPhase.Points;
            
            // Add Data to PointList
            listPhaseA.Add((XDate)DateTime, PhaseAVal);
            listPhaseB.Add((XDate)DateTime, PhaseBVal);
            listPhaseC.Add((XDate)DateTime, PhaseCVal);

            // Make sure the Y axis is rescaled to accommodate actual data & Force a redraw
            this.updateGraph();

        } //updateHistoricCurves

        /* Update Data in Realtime Graph - normally in timer control */
        public void updateHistoricCurves(DateTime DateTime, double PhaseAVal, double PhaseBVal, double PhaseCVal, double PhaseNVal)
        {
            // Reference to Graph Pane
            GraphPane graphPane = zedGraph.GraphPane;

            // Make sure that the curvelist has at least one curve
            if (graphPane.CurveList.Count <= 0)
            {
                return;
            }//if

            // Get the first CurveItem in the graph
            LineItem curveAPhase = (LineItem)graphPane.CurveList[0];
            LineItem curveBPhase = (LineItem)graphPane.CurveList[1];
            LineItem curveCPhase = (LineItem)graphPane.CurveList[2];
            LineItem curveNPhase = (LineItem)graphPane.CurveList[3];

            // Get the PointPairList
            PointPairList listPhaseA = (PointPairList)curveAPhase.Points;
            PointPairList listPhaseB = (PointPairList)curveBPhase.Points;
            PointPairList listPhaseC = (PointPairList)curveCPhase.Points;
            PointPairList listPhaseN = (PointPairList)curveNPhase.Points;

            // Add Data to PointList
            listPhaseA.Add((XDate)DateTime, PhaseAVal);
            listPhaseB.Add((XDate)DateTime, PhaseBVal);
            listPhaseC.Add((XDate)DateTime, PhaseCVal);
            listPhaseN.Add((XDate)DateTime, PhaseNVal);

            // Make sure the Y axis is rescaled to accommodate actual data & Force a redraw
            this.updateGraph();

        } //updateHistoricCurves
    

    // ---------------------------------------------------------------------------------------------------------- //
        /* Historic Bar Graph */

        /* Pane Bar Curve Creation - overloaded */
        public void createHistoricBarCurves(string strKWAh, string strKVAh, string strKVARh)
        {        
            // Reference to Graph Pane
            GraphPane graphPane = zedGraph.GraphPane;

            // Create Data Lists - <Date, Double>
            PointPairList listKWAH = new PointPairList();
            PointPairList listKVAH = new PointPairList();
            PointPairList listKVARH = new PointPairList();

            // Create Bar Items for Energy
            BarItem barKWH = graphPane.AddBar(strKWAh, listKWAH, Color.LightBlue);
            BarItem barKVAH = graphPane.AddBar(strKVAh, listKVAH, Color.LightGreen);
            BarItem barKVARH = graphPane.AddBar(strKVARh, listKVARH, Color.LightYellow);           

            // Fill the bars
            barKWH.Bar.Fill = new Fill(Color.Blue);
            barKVAH.Bar.Fill = new Fill(Color.Orange);
            barKVARH.Bar.Fill = new Fill(Color.Red);

            //Create the Bars
            graphPane.BarSettings.Type = BarType.SortedOverlay;
            //graphPane.BarSettings.ClusterScaleWidth = 1;

            // Format X Axiz
            graphPane.XAxis.Type = AxisType.DateAsOrdinal;

            graphPane.XAxis.Scale.FontSpec.Angle = 90;
            graphPane.XAxis.Scale.FontSpec.Size = 10;
            graphPane.YAxis.Scale.FontSpec.Size = 10;

            // Scale the axes
            zedGraph.AxisChange();

        } //createBarCurves


        public void updateHistoricBarCurves(List<DateTime> datetime, List<double> kwh, List<double> kvah, List<double> kvarh,string strFormat)
        {
            // Reference to Graph Pane
            GraphPane graphPane = zedGraph.GraphPane;

            // Make sure that the curvelist has at least one curve
            if (graphPane.CurveList.Count <= 0)
            {
                return;
            }//if

            //Clear curve first
            this.clearHistoricBarCurves();

            // Add BarItem References
            BarItem curveKWAH = (BarItem)graphPane.CurveList[0];
            BarItem curveKVAH = (BarItem)graphPane.CurveList[1];
            BarItem curveKVARH = (BarItem)graphPane.CurveList[2];

            // Create Data Lists - <Date, Double>
            PointPairList listKWAH = (PointPairList)curveKWAH.Points;
            PointPairList listKVAH = (PointPairList)curveKVAH.Points;
            PointPairList listKVARH = (PointPairList)curveKVARH.Points;

            // Load the Data Lists with values
            for (int count = 0; count < datetime.Count; count++)
            {
                listKWAH.Add((XDate)datetime[count], kwh[count]);
                listKVAH.Add((XDate)datetime[count], kvah[count]);
                listKVARH.Add((XDate)datetime[count], kvarh[count]);
            }//for

            switch (strFormat)
            {
                case "%h":                    
                    graphPane.XAxis.Scale.Format = "h tt";

                    // X axis step size is 1 hour
                    //graphPane.XAxis.Scale.MinorStepAuto = true;
                    //graphPane.XAxis.Scale.MinorStep = 1;
                    //graphPane.XAxis.Scale.MinorUnit = DateUnit.Hour;

                    // X axis step size is 1 hour
                    //graphPane.XAxis.Scale.MajorStepAuto = true;
                    //graphPane.XAxis.Scale.MajorStep = 1;
                    graphPane.XAxis.Scale.MajorUnit = DateUnit.Hour;
                    break;

                case "%d":
                    graphPane.XAxis.Scale.Format = "yyyy-MMM-dd";                                        

                    // X axis step size is 1 hour
                    //graphPane.XAxis.Scale.MinorStepAuto = true;
                    //graphPane.XAxis.Scale.MinorStep = 1;
                    //graphPane.XAxis.Scale.MinorUnit = DateUnit.Day;

                    // X axis step size is 1 hour
                    //graphPane.XAxis.Scale.MajorStepAuto = true;
                    //graphPane.XAxis.Scale.MajorStep = 1;
                    graphPane.XAxis.Scale.MajorUnit = DateUnit.Day;
                    break;

                case "%m":
                    graphPane.XAxis.Scale.Format = "yyyy-MMM";                                                           

                    // X axis step size is 1 hour
                    //graphPane.XAxis.Scale.MinorStepAuto = true;
                    //graphPane.XAxis.Scale.MinorStep = 1;
                    //graphPane.XAxis.Scale.MinorUnit = DateUnit.Month;

                    // X axis step size is 1 hour
                    //graphPane.XAxis.Scale.MajorStepAuto = true;
                    graphPane.XAxis.Scale.MajorUnit = DateUnit.Month;
                    break;
            } //switch 

            this.updateGraph();
        } //updateBarCurves

        // Clear BarCurves in the List
        public void clearHistoricBarCurves()
        {
            // Reference to Graph Pane
            GraphPane graphPane = zedGraph.GraphPane;

            // Iterate over all curveItems in Pane
            foreach (BarItem curveBarItem in graphPane.CurveList)
            {
                // Clear curveItems
                curveBarItem.Clear();
            }

            this.updateGraph();
        }//clearBarCurves

    } //class
} //namespace